"""
Scrapyd爬虫管理API端点
提供对Scrapyd服务器的完整管理功能
"""
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query, Body
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_active_user, get_db
from app.models.user import User
from app.services.scrapyd_service import scrapyd_service, scrapyd_web_integration
from app.core.logging import get_logger

logger = get_logger(__name__)

router = APIRouter()


@router.get("/daemon/status", response_model=Dict[str, Any])
async def get_daemon_status(
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取Scrapyd服务器状态"""
    try:
        result = await scrapyd_service.get_daemon_status()
        return result
    except Exception as e:
        logger.error(f"Failed to get daemon status: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get daemon status: {str(e)}"
        )


@router.get("/projects", response_model=Dict[str, Any])
async def get_projects(
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取所有项目列表"""
    try:
        result = await scrapyd_service.get_projects()
        return result
    except Exception as e:
        logger.error(f"Failed to get projects: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get projects: {str(e)}"
        )


@router.get("/projects/{project}/spiders", response_model=Dict[str, Any])
async def get_spiders(
    project: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取指定项目的爬虫列表"""
    try:
        result = await scrapyd_service.get_spiders(project)
        return result
    except Exception as e:
        logger.error(f"Failed to get spiders for project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get spiders: {str(e)}"
        )


@router.get("/projects/{project}/jobs", response_model=Dict[str, Any])
async def get_jobs(
    project: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取指定项目的任务列表"""
    try:
        result = await scrapyd_service.get_jobs(project)
        return result
    except Exception as e:
        logger.error(f"Failed to get jobs for project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get jobs: {str(e)}"
        )


@router.post("/projects/{project}/spiders/{spider}/schedule", response_model=Dict[str, Any])
async def schedule_spider(
    project: str,
    spider: str,
    settings: Optional[Dict[str, Any]] = Body(None),
    spider_args: Optional[Dict[str, Any]] = Body(None),
    webhook_url: Optional[str] = Body(None),
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """调度爬虫运行"""
    try:
        if webhook_url:
            result = await scrapyd_web_integration.schedule_spider_with_webhook(
                spider_name=spider,
                project=project,
                settings=settings,
                spider_args=spider_args,
                webhook_url=webhook_url
            )
        else:
            result = await scrapyd_service.schedule_spider(
                spider_name=spider,
                project=project,
                settings=settings,
                spider_args=spider_args
            )
        
        if result.get("status") == "error":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.get("message", "Failed to schedule spider")
            )
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to schedule spider {spider} in project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to schedule spider: {str(e)}"
        )


@router.post("/projects/{project}/jobs/{job_id}/cancel", response_model=Dict[str, Any])
async def cancel_job(
    project: str,
    job_id: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """取消正在运行的任务"""
    try:
        result = await scrapyd_service.cancel_job(job_id, project)
        
        if result.get("status") == "error":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.get("message", "Failed to cancel job")
            )
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to cancel job {job_id} in project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to cancel job: {str(e)}"
        )


@router.get("/projects/{project}/jobs/{job_id}/log", response_model=Dict[str, Any])
async def get_job_log(
    project: str,
    job_id: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取任务日志"""
    try:
        result = await scrapyd_service.get_job_log(job_id, project)
        return result
    except Exception as e:
        logger.error(f"Failed to get log for job {job_id} in project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get job log: {str(e)}"
        )


@router.get("/dashboard", response_model=Dict[str, Any])
async def get_dashboard(
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取ScrapydWeb仪表板数据"""
    try:
        result = await scrapyd_web_integration.get_dashboard_data()
        return result
    except Exception as e:
        logger.error(f"Failed to get dashboard data: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get dashboard: {str(e)}"
        )


@router.get("/projects/{project}/spiders/{spider_name}/stats", response_model=Dict[str, Any])
async def get_spider_stats(
    project: str,
    spider_name: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取爬虫统计信息"""
    try:
        result = await scrapyd_web_integration.get_spider_stats(project, spider_name)
        return result
    except Exception as e:
        logger.error(f"Failed to get stats for spider {spider_name} in project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get spider stats: {str(e)}"
        )


@router.post("/projects/{project}/deploy", response_model=Dict[str, Any])
async def deploy_project(
    project: str,
    egg_file_path: str,
    version: Optional[str] = Body(None),
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """部署项目到Scrapyd服务器"""
    try:
        result = await scrapyd_service.deploy_project(egg_file_path, project, version)
        
        if result.get("status") == "error":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.get("message", "Failed to deploy project")
            )
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to deploy project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to deploy project: {str(e)}"
        )


@router.delete("/projects/{project}", response_model=Dict[str, Any])
async def delete_project(
    project: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """删除项目"""
    try:
        result = await scrapyd_service.delete_project(project)
        
        if result.get("status") == "error":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.get("message", "Failed to delete project")
            )
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to delete project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to delete project: {str(e)}"
        )


@router.delete("/projects/{project}/versions/{version}", response_model=Dict[str, Any])
async def delete_version(
    project: str,
    version: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """删除项目版本"""
    try:
        result = await scrapyd_service.delete_version(project, version)
        
        if result.get("status") == "error":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.get("message", "Failed to delete version")
            )
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to delete version {version} of project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to delete version: {str(e)}"
        )


@router.get("/projects/{project}/versions", response_model=Dict[str, Any])
async def get_project_versions(
    project: str,
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """获取项目版本列表"""
    try:
        result = await scrapyd_service.get_project_versions(project)
        return result
    except Exception as e:
        logger.error(f"Failed to get versions for project {project}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get project versions: {str(e)}"
        )